package com.ymh.lock;

import com.ymh.dao.LockMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * 数据库实现分布式锁
 * Created by aivin on 2018/7/25.
 */
@Service
public class MysqlLock implements Lock {

    @Autowired
    private LockMapper lockMapper;

    //所有的线程都往数据库插入主键值相同的数据
    private static final int LOCK_ID = 1;

    //阻塞式加锁
    @Override
    public void lock() {
        //尝试加锁
        if (tryLock()) {//先调用非阻塞式加锁方式尝试加锁
            return;
        }
        //如果没加上阻塞当前线程
        waitForLock();
        //递归调用再尝试加锁
        lock();
    }

    //让当前线程休眠一段时间
    private void waitForLock() {
        try {
            Thread.currentThread().sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    //非阻塞式加锁
    @Override
    public boolean tryLock() {
        try {
            lockMapper.insert(LOCK_ID);//开始加锁
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    //解锁
    @Override
    public void unlock() {
        lockMapper.deleteByPrimaryKey(LOCK_ID);
    }


    //======================================================
    @Override
    public void lockInterruptibly() throws InterruptedException {

    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return false;
    }

    @Override
    public Condition newCondition() {
        return null;
    }
}
